package io.fatmore.web.util;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.kotlin.KotlinModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * 
 * <b><code>JsonUtil</code></b>
 * <p>
 * 
 * </p>
 * <b>Creation Time:</b> 2016年9月12日 下午6:00:19
 * @author shangkun.lsk@fastmor.com
 * @since ucun-finance
 */
public class JsonUtil {

	private static volatile ObjectMapper objectMapper = null;
	
	private static final Logger logger = LoggerFactory.getLogger(JsonUtil.class);

	/**
	* 对象转化为json字符串
	*/
	public static String toJson(Object obj) {
		ObjectMapper mapper = getObjectMapper();
		try {

			return mapper.writeValueAsString(obj);

		} catch (JsonGenerationException e) {
			e.printStackTrace();
			logger.debug("json to java error",e);
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 格式化为格式后的json
	 * @param obj
	 * @return
	 */
	public static String formatJson(Object obj) {
		String json = toJson(obj);
		if (json == null) {
			return null;
		}
		return JsonParseTool.formatJson(json);

	}

	/**
	 * json字符串转化为对象
	 *
	 * @param <T>
	 * @param jsonStr
	 * @param clazz
	 * @return
	 */
	public static <T> T toJava(String jsonStr, Class<T> clazz) {
		try {
			ObjectMapper mapper = getObjectMapper();
			return mapper.readValue(jsonStr, clazz);
		} catch (JsonParseException e) {
			e.printStackTrace();
			logger.debug("parse json error",e);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * json 字符串转对象（泛型）
	 * @param jsonStr
	 * @param typeReference
	 * @return
	 */

	public static <T> T toJava(String jsonStr, TypeReference<T> typeReference) {
		try {
			ObjectMapper mapper = getObjectMapper();
			return mapper.readValue(jsonStr, typeReference);
		} catch (JsonParseException e) {
			e.printStackTrace();
			logger.debug("parse json error",e);
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取Jackson的ObjectMapper。使用单例模式，提高性能。
	 *
	 * @return
	 */
	public static ObjectMapper getObjectMapper() {
		if (objectMapper == null) {
			synchronized (ObjectMapper.class) {
				if (objectMapper == null) {
					objectMapper = new ObjectMapper();
					objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
					objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
					objectMapper.registerModule(new KotlinModule());
				}
			}
		}
		return objectMapper;
	}
}
